/****************************************************************************
  *
  * Header Files
  *
  ****************************************************************************/
#include "ctc_asw_common.h"
#include "ctc_asw_qos.h"
#include "ctc_packet.h"
#include "ctc_pdu.h"
#include "ctc_asw_port.h"
#include "ctc_asw_chip.h"
#include "ctc_asw_register.h"

#include "asw/include/drv_api.h"
/****************************************************************************
  *
  * Defines and Macros
  *
  ****************************************************************************/
#define SYS_QOS_CLASS_COLOR_MAX (MAX_CTC_QOS_COLOR - 1)
#define SYS_QOS_CLASS_COS_MAX 7
#define SYS_QOS_CLASS_CFI_MAX 1
#define SYS_QOS_CLASS_DSCP_MAX 63
#define SYS_QOS_CLASS_ECN_MAX 3
#define CTC_ASW_QOS_MAX_CPU_QUE_ID 47
#define CTC_ASW_HW_CPU_REASON_KNOWN_DA 1
#define CTC_ASW_HW_CPU_REASON_UNKNOWN_DA 2
#define CTC_ASW_HW_CPU_REASON_SMAC_FWD 3
#define CTC_ASW_HW_CPU_REASON_PMAC_FWD 4
#define CTC_ASW_HW_CPU_REASON_SVLAN_FWD 5
#define CTC_ASW_HW_CPU_REASON_ACL_FWD 6
#define CTC_ASW_HW_CPU_REASON_CPU_TAG 8
#define CTC_ASW_HW_CPU_REASON_SMAC 12
#define CTC_ASW_HW_CPU_REASON_PMAC 13
#define CTC_ASW_HW_CPU_REASON_ACL_MATCH 14
#define CTC_ASW_HW_CPU_REASON_MIRROR_COPY 15
#define CTC_ASW_HW_CPU_REASON_IP_HAVE_OPTION 17
#define CTC_ASW_HW_CPU_REASON_IVT_UNKNOWN 18
#define CTC_ASW_HW_CPU_REASON_IVT_CHK_FAIL 19
#define CTC_ASW_QOS_MAX_POLICER_ID 63
#define CTC_ASW_QOS_FLOW_CTRL_THRESHOLD 4096
#define CTC_ASW_QOS_GLB_MMU_RES 0x150
#define CTC_ASW_QOS_MAX_CHIP_PBS_PIR 0x3FFFF8
#define CTC_ASW_QOS_MAX_CHIP_PPS_PIR 0x7FFFF
#define CTC_ASW_QOS_MAX_CHIP_PBS 0x7D8
#define CTC_ASW_QOS_GLB_CELL_DROP 0x180
#define CTC_ASW_QOS_GLB_CELL_PAUSE 0x1FF
#define CTC_ASW_QOS_GLB_CELL_OFFSET 0x10
#define CTC_ASW_QOS_GLB_PKT_SHARE 0xe0
#define CTC_ASW_QOS_SHAPE_IPG_DEFAULT 24
#define CTC_ASW_QOS_SHAPE_IPG_MIN 4
#define CTC_ASW_QOS_MAX_QUE_ID 7
#define CTC_FLOW_CTL_BUFFER_MAX_PORT_NUM 20
#define CTC_CHIP_BUFFER_CELL_MAX   3072
#define CTC_CHIP_BUFFER_PACKET_MAX 1024
#define CTC_ASW_QOS_GLB_SHARE 0x180
#define CTC_ASW_QOS_GLB_QUE_SHARE 0x180
#define CTC_ASW_QOS_GLB_SHAPE_THREHOLD 0xFB0
#define CTC_ASW_QOS_GLB_POLICER_THREHOLD 0xFB0
#define CTC_ASW_QOS_MAX_CHIP_PIR 0x3FFFF8
#define CTC_ASW_QOS_GLB_MIN_THREHOLD 0x26
#define CTC_ASW_QOS_QUE_MIN_SHARE 0x14
#define CTC_ASW_QOS_POLICER_STATS_MODE_MAX 1
#define CTC_ASW_QOS_POLICER_STATS_COLOR_AWARE 3
#define CTC_ASW_QOS_POLICER_STATS_COLOR_BLIND 0
#define CTC_ASW_QOS_POLICER_STATS_DISABLE 5
#define CTC_ASW_QOS_POLICER_STATS_ID(policer_id) (policer_id+CTC_ASW_MAX_STATS_ID+1)
#define CTC_ASW_QOS_MAX_USER_DEFINE_REASON_NUM  48
#define CTC_ASW_QOS_CPU_REASON_DST_FLD_CNT  5
#define CTC_ASW_QOS_MAX_WEIGHT 0X7F

uint32  policer_bitmap[CTC_MAX_LOCAL_CHIP_NUM][2] = {0};
uint8  user_define_cpu_reason[CTC_MAX_LOCAL_CHIP_NUM][CTC_ASW_QOS_MAX_USER_DEFINE_REASON_NUM] = {0};
/****************************************************************************
 *
 * Function
 *
 ****************************************************************************/
#define ______INTERNAL______
STATIC int32
_ctc_qos_flowctl_init(uint8 lchip)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 value = 0;
    EgMmuGlbCtrl_m ds_eg_mmu_glb_ctrl;
    PCellShareProfile_m ds_p_cell_share_profile;
    PCellLimitYellowProfile_m ds_p_cell_limit_yellow_profile;
    PCellLimitRedProfile_m ds_p_cell_limit_red_profile;
    QCellLimitYellowProfile_m ds_q_cell_limit_yellow_profile;
    QCellLimitRedProfile_m ds_q_cell_limit_red_profile;
    cmd = DRV_IOR(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
    ret =  DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);
    /* for spec bug 126453, enable 3 cell on erm */
    cmd = DRV_IOR(DeviceId_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, cmd, &value);
    if (0 == ((value>>16) & 0xF))
    {
        SetEgMmuGlbCtrl(V, offsetThd_f, &ds_eg_mmu_glb_ctrl, 0x10);
    }
    else
    {
        SetEgMmuGlbCtrl(V, offsetThd_f, &ds_eg_mmu_glb_ctrl, 0x11);
    }
    SetEgMmuGlbCtrl(V, limitYellowThd_f, &ds_eg_mmu_glb_ctrl, 0x180);
    SetEgMmuGlbCtrl(V, offsetYellowThd_f, &ds_eg_mmu_glb_ctrl, 0x10);
    SetEgMmuGlbCtrl(V, limitRedThd_f, &ds_eg_mmu_glb_ctrl, 0x180);
    SetEgMmuGlbCtrl(V, offsetRedThd_f, &ds_eg_mmu_glb_ctrl, 0x10);
    cmd = DRV_IOW(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);

    cmd = DRV_IOR(PCellShareProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_p_cell_share_profile);
    SetPCellShareProfile(V, shareThd_f, &ds_p_cell_share_profile, 0x180);
    cmd = DRV_IOW(PCellShareProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_p_cell_share_profile);

    cmd = DRV_IOR(PCellLimitYellowProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_p_cell_limit_yellow_profile);
    SetPCellLimitYellowProfile(V, thd_f, &ds_p_cell_limit_yellow_profile, 0x180);
    cmd = DRV_IOW(PCellLimitYellowProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_p_cell_limit_yellow_profile);

    cmd = DRV_IOR(PCellLimitRedProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_p_cell_limit_red_profile);
    SetPCellLimitRedProfile(V, thd_f, &ds_p_cell_limit_red_profile, 0x180);
    cmd = DRV_IOW(PCellLimitRedProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_p_cell_limit_red_profile);

    cmd = DRV_IOR(QCellLimitYellowProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_limit_yellow_profile);
    SetQCellLimitYellowProfile(V, thd_f, &ds_q_cell_limit_yellow_profile, 0x180);
    cmd = DRV_IOW(QCellLimitYellowProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_limit_yellow_profile);

    cmd = DRV_IOR(QCellLimitRedProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_limit_red_profile);
    SetQCellLimitRedProfile(V, thd_f, &ds_q_cell_limit_red_profile, 0x180);
    cmd = DRV_IOW(QCellLimitRedProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_limit_red_profile);

    return ret;
}

STATIC int32
_ctc_qos_alloc_res_for_flowcontrol(uint8 lchip, uint32* p_gport,uint32 version, uint32 port_num)
{
    uint32 port_id = 0;
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    IngMmuGlbCtrl_m ds_ing_mmu_glb_ctrl;
    IngMmuPortCtrl_m ds_ing_mmu_port_ctrl;
    EgMmuGlbCtrl_m ds_eg_mmu_glb_ctrl;
    QCellShareProfile_m ds_q_cell_share_profile;
    QCellMinProfile_m ds_q_cell_min_profile;
    uint32 ing_mmu_glb_ctrl_arry[2][9] =
    {
        /*ingress mmu glb param, thd_drop_en/pkt_drop/pkt_pause/pkt_offset/pkt_share/cell_drop/cell_pause/cell_offset/cell_share*/
        {0x01,0xff,0xff,0x10,0xe0,0x180,0x1ff,0x10,0x150},
        {0x01,0xff,0xff,0x10,0xd8,0x180,0x1ff,0x10,0xc8}
    };
    uint32 ing_mmu_port_ctrl_arry[2][10] =
    {
        /*ingress mmu port param, cellHead_f/cellOffset_f/cellShare_f/cellDynamic_f/cellMin_f/pktHead_f/pktOffset_f/pktShare_f/pktDynamic_f/pktMin_f*/
        {0x20,0x0a,0x03,0x01,0x00,0x10,0x06,0x03,0x01,0x01},
        {0x20,0x05,0x03,0x01,0x13,0x10,0x06,0x03,0x01,0x01}
    };

    /* for chip 1.0 */
    if (0 == version)
    {
        cmd = DRV_IOR(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);
        SetIngMmuGlbCtrl(V, thdDropEn_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][0]);
        SetIngMmuGlbCtrl(V, pktDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][1]);
        SetIngMmuGlbCtrl(V, pktPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][2]);
        SetIngMmuGlbCtrl(V, pktOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][3]);
        SetIngMmuGlbCtrl(V, pktShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][4]);
        SetIngMmuGlbCtrl(V, cellDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][5]);
        SetIngMmuGlbCtrl(V, cellPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][6]);
        SetIngMmuGlbCtrl(V, cellOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][7]);
        SetIngMmuGlbCtrl(V, cellShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][8]);
        cmd = DRV_IOW(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);

        for (port_id = 0; port_id < port_num; port_id++)
        {
            cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
            SetIngMmuPortCtrl(V, cellHead_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][0]);
            SetIngMmuPortCtrl(V, cellOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][1]);
            SetIngMmuPortCtrl(V, cellShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][2]);
            SetIngMmuPortCtrl(V, cellDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][3]);
            SetIngMmuPortCtrl(V, cellMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][4]);
            SetIngMmuPortCtrl(V, pktHead_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][5]);
            SetIngMmuPortCtrl(V, pktOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][6]);
            SetIngMmuPortCtrl(V, pktShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][7]);
            SetIngMmuPortCtrl(V, pktDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][8]);
            SetIngMmuPortCtrl(V, pktMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][9]);
            cmd = DRV_IOW(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
        }
    }
    /* for chip 1.1 */
    else
    {
        cmd = DRV_IOR(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);
        SetIngMmuGlbCtrl(V, thdDropEn_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][0]);
        SetIngMmuGlbCtrl(V, pktDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][1]);
        SetIngMmuGlbCtrl(V, pktPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][2]);
        SetIngMmuGlbCtrl(V, pktOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][3]);
        SetIngMmuGlbCtrl(V, pktShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][4]);
        SetIngMmuGlbCtrl(V, cellDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][5]);
        SetIngMmuGlbCtrl(V, cellPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][6]);
        SetIngMmuGlbCtrl(V, cellOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][7]);
        if (port_num <= CTC_FLOW_CTL_BUFFER_MAX_PORT_NUM)
        {
            SetIngMmuGlbCtrl(V, cellShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][8]);
        }
        else
        {
            SetIngMmuGlbCtrl(V, cellShare_f, &ds_ing_mmu_glb_ctrl, 0x148);
        }
        cmd = DRV_IOW(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);

        for (port_id = 0; port_id < port_num; port_id++)
        {
            cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
            SetIngMmuPortCtrl(V, cellHead_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][0]);
            SetIngMmuPortCtrl(V, cellOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][1]);
            SetIngMmuPortCtrl(V, cellShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][2]);
            SetIngMmuPortCtrl(V, cellDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][3]);
            if (port_num <= CTC_FLOW_CTL_BUFFER_MAX_PORT_NUM)
            {
                SetIngMmuPortCtrl(V, cellMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][4]);
            }
            else
            {
                SetIngMmuPortCtrl(V, cellMin_f, &ds_ing_mmu_port_ctrl, 0x03);
            }
            SetIngMmuPortCtrl(V, pktHead_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][5]);
            SetIngMmuPortCtrl(V, pktOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][6]);
            SetIngMmuPortCtrl(V, pktShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][7]);
            SetIngMmuPortCtrl(V, pktDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][8]);
            SetIngMmuPortCtrl(V, pktMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][9]);
            cmd = DRV_IOW(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
        }
    }

    cmd = DRV_IOR(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);
    SetEgMmuGlbCtrl(V, shareThd_f, &ds_eg_mmu_glb_ctrl, CTC_ASW_QOS_GLB_SHARE);
    cmd = DRV_IOW(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);

    cmd = DRV_IOR(QCellShareProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_share_profile);
    SetQCellShareProfile(V, shareThd_f, &ds_q_cell_share_profile, CTC_ASW_QOS_GLB_QUE_SHARE);
    SetQCellShareProfile(V, dynamicEn_f, &ds_q_cell_share_profile, 0x00);
    cmd = DRV_IOW(QCellShareProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_share_profile);

    cmd = DRV_IOR(QCellMinProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_min_profile);
    SetQCellMinProfile(V, minThd_f, &ds_q_cell_min_profile, 0x00);
    cmd = DRV_IOW(QCellMinProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_min_profile);

    return ret;
}

STATIC int32
_ctc_qos_alloc_res_for_snake(uint8 lchip, uint32* p_gport,uint32 version, uint32 port_num)
{
    uint8 port_id = 0;
    uint32 cell_head = 0;
    uint8 packet_head = 0;
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    IngMmuGlbCtrl_m ds_ing_mmu_glb_ctrl;
    IngMmuPortCtrl_m ds_ing_mmu_port_ctrl;
    EgMmuGlbCtrl_m ds_eg_mmu_glb_ctrl;
    QCellShareProfile_m ds_q_cell_share_profile;
    QCellMinProfile_m ds_q_cell_min_profile;
    const uint32 ing_mmu_glb_ctrl_arry[2][9] =
    {
        /*ingress mmu glb param, thd_drop_en/pkt_drop/pkt_pause/pkt_offset/pkt_share/cell_drop/cell_pause/cell_offset/cell_share*/
        {0x01,0xff,0xff,0x10,0x0,0x180,0x1ff,0x10,0x0},
        {0x01,0xff,0xff,0x10,0xff,0x180,0x1ff,0x10,0x180}
    };
    const uint32 ing_mmu_port_ctrl_arry[2][10] =
    {
        /*ingress mmu port param, cell_head/cell_offset/cell_share/cell_dynamic/cell_min/pkt_head/pkt_offset/pkt_share/pkt_dynamic/pkt_min*/
        {0x20,0x00,0x00,0x00,0x03,0x10,0x00,0x00,0x00,0x01},
        {0x20,0x10,0x180,0x00,0x00,0x20,0x10,0xff,0x00,0x00}
    };

    /* for chip 1.0 */
    if (0 == version)
    {
        cmd = DRV_IOR(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);
        SetIngMmuGlbCtrl(V, thdDropEn_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][0]);
        SetIngMmuGlbCtrl(V, pktDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][1]);
        SetIngMmuGlbCtrl(V, pktPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][2]);
        SetIngMmuGlbCtrl(V, pktOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][3]);
        SetIngMmuGlbCtrl(V, pktShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][4]);
        SetIngMmuGlbCtrl(V, cellDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][5]);
        SetIngMmuGlbCtrl(V, cellPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][6]);
        SetIngMmuGlbCtrl(V, cellOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][7]);
        SetIngMmuGlbCtrl(V, cellShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[0][8]);
        cmd = DRV_IOW(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);

        /* set convergence ratio as 2.5 */
        cell_head = CTC_CHIP_BUFFER_CELL_MAX * 5 / 16 / port_num;
        if (cell_head > 96)
        {
            cell_head = 96;
        }
        else if (cell_head < 32)
        {
            cell_head = 32;
        }

        packet_head = CTC_CHIP_BUFFER_PACKET_MAX * 5 / 8 / port_num;
        if (packet_head > 32)
        {
            packet_head = 32;
        }
        else if (packet_head < 20) /* bug 358, min packet_cnt must over 0x4b */
        {
            packet_head = 20;
        }

        for (port_id = 0; port_id < port_num; port_id++)
        {
            cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
            SetIngMmuPortCtrl(V, cellHead_f, &ds_ing_mmu_port_ctrl, cell_head);
            SetIngMmuPortCtrl(V, cellOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][1]);
            SetIngMmuPortCtrl(V, cellShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][2]);
            SetIngMmuPortCtrl(V, cellDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][3]);
            SetIngMmuPortCtrl(V, cellMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][4]);
            SetIngMmuPortCtrl(V, pktHead_f, &ds_ing_mmu_port_ctrl, packet_head);
            SetIngMmuPortCtrl(V, pktOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][6]);
            SetIngMmuPortCtrl(V, pktShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][7]);
            SetIngMmuPortCtrl(V, pktDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][8]);
            SetIngMmuPortCtrl(V, pktMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[0][9]);
            cmd = DRV_IOW(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
        }

        cmd = DRV_IOR(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);
        SetEgMmuGlbCtrl(V, shareThd_f, &ds_eg_mmu_glb_ctrl, 0x180);
        cmd = DRV_IOW(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);

        cmd = DRV_IOR(QCellShareProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_share_profile);
        SetQCellShareProfile(V, shareThd_f, &ds_q_cell_share_profile, 0x180);
        SetQCellShareProfile(V, dynamicEn_f, &ds_q_cell_share_profile, 0x00);
        cmd = DRV_IOW(QCellShareProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_share_profile);
        cmd = DRV_IOR(QCellMinProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_min_profile);
        SetQCellMinProfile(V, minThd_f, &ds_q_cell_min_profile, 0x00);
        cmd = DRV_IOW(QCellMinProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_min_profile);
    }
    /* for chip 1.1 */
    else
    {
        cmd = DRV_IOR(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);
        if (port_num <= CTC_FLOW_CTL_BUFFER_MAX_PORT_NUM)
        {
            SetEgMmuGlbCtrl(V, shareThd_f, &ds_eg_mmu_glb_ctrl, 0xe8);
        }
        else
        {
            SetEgMmuGlbCtrl(V, shareThd_f, &ds_eg_mmu_glb_ctrl, 0x168);
        }
        cmd = DRV_IOW(EgMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_eg_mmu_glb_ctrl);
        cmd = DRV_IOR(QCellShareProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_share_profile);
        SetQCellShareProfile(V, shareThd_f, &ds_q_cell_share_profile, 0x04);
        SetQCellShareProfile(V, dynamicEn_f, &ds_q_cell_share_profile, 0x01);
        cmd = DRV_IOW(QCellShareProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_share_profile);

        cmd = DRV_IOR(QCellMinProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_min_profile);
        if (port_num <= CTC_FLOW_CTL_BUFFER_MAX_PORT_NUM)
        {
            SetQCellMinProfile(V, minThd_f, &ds_q_cell_min_profile, 0x13);
        }
        else
        {
            SetQCellMinProfile(V, minThd_f, &ds_q_cell_min_profile, 0x03);
        }
        cmd = DRV_IOW(QCellMinProfile_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_q_cell_min_profile);

        cmd = DRV_IOR(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);
        SetIngMmuGlbCtrl(V, thdDropEn_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][0]);
        SetIngMmuGlbCtrl(V, pktDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][1]);
        SetIngMmuGlbCtrl(V, pktPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][2]);
        SetIngMmuGlbCtrl(V, pktOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][3]);
        SetIngMmuGlbCtrl(V, pktShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][4]);
        SetIngMmuGlbCtrl(V, cellDrop_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][5]);
        SetIngMmuGlbCtrl(V, cellPause_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][6]);
        SetIngMmuGlbCtrl(V, cellOffset_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][7]);
        SetIngMmuGlbCtrl(V, cellShare_f, &ds_ing_mmu_glb_ctrl, ing_mmu_glb_ctrl_arry[1][8]);
        cmd = DRV_IOW(IngMmuGlbCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds_ing_mmu_glb_ctrl);

        for (port_id = 0; port_id < port_num; port_id++)
        {
            cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
            SetIngMmuPortCtrl(V, cellHead_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][0]);
            SetIngMmuPortCtrl(V, cellOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][1]);
            SetIngMmuPortCtrl(V, cellShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][2]);
            SetIngMmuPortCtrl(V, cellDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][3]);
            SetIngMmuPortCtrl(V, cellMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][4]);
            SetIngMmuPortCtrl(V, pktHead_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][5]);
            SetIngMmuPortCtrl(V, pktOffset_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][6]);
            SetIngMmuPortCtrl(V, pktShare_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][7]);
            SetIngMmuPortCtrl(V, pktDynamic_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][8]);
            SetIngMmuPortCtrl(V, pktMin_f, &ds_ing_mmu_port_ctrl, ing_mmu_port_ctrl_arry[1][9]);
            cmd = DRV_IOW(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, p_gport[port_id], cmd, &ds_ing_mmu_port_ctrl);
        }
    }
    return ret;
}

/**
 @brief Queue dropping initialization.
*/
STATIC int32
_ctc_asw_qos_glb_res_init(uint8 lchip, void *p_glb_parm)
{
    int32 ret = CTC_E_NONE;
    uint32 p_cnt = 0;
    uint32 cmd = 0;
    uint32 version = 0;
    uint32 value = 0;
    uint32 p_gport[CTC_ASW_MAX_PORT_NUM_PER_CHIP] = {0};
    ctc_qos_global_cfg_t * p_glb_cfg = NULL;

    p_glb_cfg = (ctc_qos_global_cfg_t *)p_glb_parm;
    cmd = DRV_IOR(DeviceId_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, 0, cmd, &value);
    if (0 == ((value>>16) & 0xF))
    {
        version = 0;
    }
    else
    {
        version = 1;
    }
    CTC_ERROR_RETURN(_ctc_asw_datapath_get_gports(lchip,p_gport,&p_cnt));
    if(p_glb_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_MODE1)
    {
        /* ingress dynamic drop */
        CTC_ERROR_RETURN(_ctc_qos_alloc_res_for_flowcontrol(lchip,p_gport,version,p_cnt));
    }
    else if (p_glb_cfg->resrc_pool.igs_pool_mode == CTC_QOS_RESRC_POOL_DISABLE)
    {
        /* for 1.0, ingress static drop; for 1.1 egress dynamic drop */
        CTC_ERROR_RETURN(_ctc_qos_alloc_res_for_snake(lchip,p_gport,version,p_cnt));
    }

    return ret;
}

STATIC uint16
_ctc_asw_qos_check_and_get_policer_id(uint8 lchip, uint8 type, uint16 policer_id, uint32 gport, uint32* p_policer_id)
{
    uint32 value = 0;
    uint32 tmp_policer_id = 0;

    switch(type)
    {
        case CTC_QOS_POLICER_TYPE_PORT:
            CTC_MAX_GPORT_CHECK(gport);           
            /*get port policer enable*/
            CTC_ERROR_RETURN(ctc_asw_port_get_direction_property(lchip, gport,CTC_PORT_DIR_PROP_PORT_POLICER_VALID, CTC_INGRESS,&value));
            value = value&0xff;
            if (value)
            {
                /*get port policer ptr*/
                CTC_ERROR_RETURN(_ctc_asw_port_get_internal_property(lchip, gport,CTC_PORT_INT_PROP_INGRESS_POLICER_PTR,&tmp_policer_id));
            }
            else
            {
                return CTC_E_NOT_EXIST;
            }
            break;
        case CTC_QOS_POLICER_TYPE_FLOW:
            CTC_MAX_VALUE_CHECK(policer_id,CTC_ASW_QOS_MAX_POLICER_ID);
            if (policer_id == 0)
            {
                return CTC_E_NOT_EXIST;
            }
            if(CTC_E_EXIST == _ctc_asw_bitmap_check_active(lchip,policer_bitmap[lchip],policer_id))
            {
                tmp_policer_id = policer_id;
            }
            else
            {
                return CTC_E_NOT_EXIST;
            }
            break;
        default:
            return CTC_E_NONE;
            break;
    }
    *p_policer_id = tmp_policer_id;

    return CTC_E_NONE;
}

STATIC int32
_ctc_asw_qos_set_cpu_reason_queue(uint8 lchip, uint16 cpu_reason, uint8 queue_id)
{
    int32 ret = CTC_E_NONE;
    ds_t ds;
    uint32 cmd = 0;
    uint16 index = 0;
    uint16 index_start = 0;
    uint16 index_end = 0;
    uint32 tbl_id = 0;
    uint32 field_id[2] = {0};

    if ((cpu_reason >= CTC_PKT_CPU_REASON_L2_PDU)
        && (cpu_reason <(CTC_PKT_CPU_REASON_L2_PDU+CTC_ASW_SPMAC_KEY_NUM+CTC_ASW_PMAC_KEY_NUM)))
    {
        uint32 action_index = cpu_reason-CTC_PKT_CPU_REASON_L2_PDU;
        if (action_index < CTC_ASW_SPMAC_KEY_NUM)
        {
            tbl_id = SmacAct_t;
            field_id[0] = SmacAct_changeQp2cpu_f;
            field_id[1] = SmacAct_qp2cpu_f;
        }
        else
        {
            tbl_id = PmacAct_t;
            field_id[0] = PmacAct_changeQp2cpu_f;
            field_id[1] = PmacAct_qp2cpu_f;
            action_index -= CTC_ASW_SPMAC_KEY_NUM;
        }
        
        for (index = 0; index<CTC_ASW_MAX_SPMAC_GROUP; index++)
        {
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, index+CTC_ASW_MAX_SPMAC_GROUP*action_index, cmd, &ds);
            DRV_SET_FIELD_V(lchip,tbl_id,field_id[0],&ds,1);
            DRV_SET_FIELD_V(lchip,tbl_id,field_id[1],&ds,queue_id);
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            ret = ret?ret:DRV_IOCTL(lchip, index+CTC_ASW_MAX_SPMAC_GROUP*action_index, cmd, &ds);
        }
    }
    else if (cpu_reason >= CTC_PKT_CPU_REASON_CUSTOM_BASE
            && (cpu_reason < CTC_PKT_CPU_REASON_CUSTOM_BASE+CTC_ASW_QOS_MAX_USER_DEFINE_REASON_NUM))
    {
        user_define_cpu_reason[lchip][cpu_reason-CTC_PKT_CPU_REASON_CUSTOM_BASE] = queue_id;
    }
    else
    {
        switch(cpu_reason)
        {
            case CTC_PKT_CPU_REASON_ACL_MATCH:
                index_start = CTC_ASW_HW_CPU_REASON_ACL_MATCH;
                break;
            case CTC_PKT_CPU_REASON_L3_IP_OPTION:
                index_start = CTC_ASW_HW_CPU_REASON_IP_HAVE_OPTION;
                break;
            case CTC_PKT_CPU_REASON_MIRRORED_TO_CPU:
                index_start = CTC_ASW_HW_CPU_REASON_MIRROR_COPY;
                break;
            case CTC_PKT_CPU_REASON_DROP:
                index_start = CTC_ASW_HW_CPU_REASON_IVT_UNKNOWN;
                index_end = CTC_ASW_HW_CPU_REASON_IVT_CHK_FAIL;
                break;
            case CTC_PKT_CPU_REASON_C2C_PKT:
                index_start = CTC_ASW_HW_CPU_REASON_CPU_TAG;
                break;
            case CTC_PKT_CPU_REASON_FWD_CPU:
                index_start = CTC_ASW_HW_CPU_REASON_KNOWN_DA;
                index_end = CTC_ASW_HW_CPU_REASON_ACL_FWD;
                break;
            default:
                ret = CTC_E_INVALID_PARAM;
                break;
        }
        index_end = index_end?index_end:index_start;
        SetTocpuQp(V, useReason2qp_f,&ds,1);
        SetTocpuQp(V, qp_f,&ds,queue_id);
        for (index= index_start; index<=index_end;index++)
        {
            cmd = DRV_IOW(TocpuQp_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, index, cmd, &ds);
        }
    }

    return ret;
}

#define ______INTERNAL_API______
int32
_ctc_asw_qos_get_cpu_reason_queue(uint8 lchip, uint16 cpu_reason, uint8* p_queue_id)
{
    int32 ret = CTC_E_NONE;
    ds_t ds;
    uint32 cmd = 0;
    uint16 index = 0;
    uint32 tbl_id = 0;
    uint32 field_id[2] = {0};

    if ((cpu_reason >= CTC_PKT_CPU_REASON_L2_PDU)
        && (cpu_reason <(CTC_PKT_CPU_REASON_L2_PDU+CTC_ASW_SPMAC_KEY_NUM+CTC_ASW_PMAC_KEY_NUM)))
    {
        uint32 action_index = cpu_reason-CTC_PKT_CPU_REASON_L2_PDU;
        if (action_index < CTC_ASW_SPMAC_KEY_NUM)
        {
            tbl_id = SmacAct_t;
            field_id[0] = SmacAct_changeQp2cpu_f;
            field_id[1] = SmacAct_qp2cpu_f;
        }
        else
        {
            tbl_id = PmacAct_t;
            field_id[0] = PmacAct_changeQp2cpu_f;
            field_id[1] = PmacAct_qp2cpu_f;
            action_index -= CTC_ASW_SPMAC_KEY_NUM;
        }
        
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, index+CTC_ASW_MAX_SPMAC_GROUP*action_index, cmd, &ds);
        if (DRV_GET_FIELD_V(lchip,tbl_id,field_id[0],&ds))
        {
            *p_queue_id = DRV_GET_FIELD_V(lchip,tbl_id,field_id[1],&ds);
        }
        else
        {
            *p_queue_id = 0xFF;
        }
    }
    else if (cpu_reason >= CTC_PKT_CPU_REASON_CUSTOM_BASE
            && (cpu_reason < CTC_PKT_CPU_REASON_CUSTOM_BASE+CTC_ASW_QOS_MAX_USER_DEFINE_REASON_NUM))
    {
        *p_queue_id = user_define_cpu_reason[lchip][cpu_reason-CTC_PKT_CPU_REASON_CUSTOM_BASE];
    }
    else
    {
        switch(cpu_reason)
        {
            case CTC_PKT_CPU_REASON_ACL_MATCH:
                index = CTC_ASW_HW_CPU_REASON_ACL_MATCH;
                break;
            case CTC_PKT_CPU_REASON_L3_IP_OPTION:
                index = CTC_ASW_HW_CPU_REASON_IP_HAVE_OPTION;
                break;
            case CTC_PKT_CPU_REASON_MIRRORED_TO_CPU:
                index = CTC_ASW_HW_CPU_REASON_MIRROR_COPY;
                break;
            case CTC_PKT_CPU_REASON_DROP:
                index = CTC_ASW_HW_CPU_REASON_IVT_UNKNOWN;
                break;
            case CTC_PKT_CPU_REASON_C2C_PKT:
                index = CTC_ASW_HW_CPU_REASON_CPU_TAG;
                break;
            case CTC_PKT_CPU_REASON_FWD_CPU:
                index = CTC_ASW_HW_CPU_REASON_KNOWN_DA;
                break;
            default:
                ret = CTC_E_INVALID_PARAM;
                break;
        }
        cmd = DRV_IOR(TocpuQp_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, index, cmd, &ds);
        if (GetTocpuQp(V, useReason2qp_f,&ds))
        {
            *p_queue_id = GetTocpuQp(V, qp_f,&ds);
        }
        else
        {
            *p_queue_id = 0xFF;
        }
    }

    if (*p_queue_id == 0xFF)
    {
        return CTC_E_INVALID_PARAM;
    }

    return ret;
}

#define ______API______
/*init*/
int32
ctc_asw_qos_init(uint8 lchip, void* p_glb_parm)
{
    int32 ret = CTC_E_NONE;
    uint8 color    = 0;
    uint8 priority = 0;
    uint8 value    = 0;
    uint8 domain   = 0;
    uint32 tbl_index  = 0;
    uint32 cmd = 0;
    uint32 i = 0;
    ctc_qos_global_cfg_t * p_glb_cfg = NULL;
    ds_t ds;

	CTC_PTR_VALID_CHECK(p_glb_parm);
    p_glb_cfg = (ctc_qos_global_cfg_t *)p_glb_parm;

    sal_memset(&ds, 0, sizeof(ds));

    for (value = 0; value < 8; value++)
    {
        priority = value * 2;
        tbl_index = (domain << 6) | (3 << 4) | (value << 1) | 0;
        SetPriLplcMapTable(V, localPri_f, &ds, priority);
        SetPriLplcMapTable(V, localColor_f, &ds, color);
        cmd = DRV_IOW(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &ds);
        tbl_index = (domain << 6) | (3 << 4) | (value << 1) | 1;
        SetPriLplcMapTable(V, localPri_f, &ds, priority);
        SetPriLplcMapTable(V, localColor_f, &ds, color);
        cmd = DRV_IOW(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &ds);
    }

    for (priority = 0; priority < 16; priority++)
    {
        for (color = CTC_QOS_COLOR_NONE; color < MAX_CTC_QOS_COLOR; color++)
        {
            value = priority>>1;
            tbl_index = (domain << 6) | (priority << 2) | color ;
            cmd = DRV_IOR(LplcPriMapTable_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &ds);
            value = (value << 1 | 0);
            SetLplcPriMapTable(V,scos_f,&ds,value);
            cmd = DRV_IOW(LplcPriMapTable_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &ds);
        }
    }
    /* map priority to queue priority */
    for (priority = 0; priority<16; priority++)
    {
        cmd = DRV_IOR(Lp2qpMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, priority, cmd, &ds);
        value = priority>>1;
        SetLp2qpMapTable(V,egportQp_f,&ds,value);
        cmd = DRV_IOW(Lp2qpMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, priority, cmd, &ds);
    }
    /* set MMU xoff default value enable */
    cmd = DRV_IOR(IngMmuXoffEn_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds);
    value = GetIngMmuXoffEn(V, enable_f, &ds);
    SetIngMmuXoffEn(V, enable_f, &ds, 0x1FFFFFFF);
    cmd = DRV_IOW(IngMmuXoffEn_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds);
    CTC_ERROR_RETURN(_ctc_qos_flowctl_init(lchip));
    CTC_ERROR_RETURN(_ctc_asw_qos_glb_res_init(lchip,p_glb_cfg));

    for (i = 0; i < CTC_ASW_MAX_PORT_NUM_PER_CHIP; i++)
    {
        cmd = DRV_IOR(SchPortMode_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, i, cmd, &ds);
        SetSchPortMode(V, quanta_f, &ds,3);
        cmd = DRV_IOW(SchPortMode_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,i, cmd, &ds);
    }
    /*cpu mac port min*/
    cmd = DRV_IOR(PCellMinProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_PORT_CELL_MIN_PROFILE, cmd, &ds);
    SetPCellMinProfile(V, minThd_f, &ds, CTC_ASW_QOS_QUE_MIN_SHARE);
    cmd = DRV_IOW(PCellMinProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip,CTC_ASW_QOS_PORT_CELL_MIN_PROFILE, cmd, &ds);

    cmd = DRV_IOR(EgPortThdCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_MAX_PHY_PORT, cmd, &ds);
    SetEgPortThdCtrl(V, minIndex_f, &ds, CTC_ASW_QOS_PORT_CELL_MIN_PROFILE);
    cmd = DRV_IOW(EgPortThdCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_MAX_PHY_PORT, cmd, &ds);

    /*mirror port share*/
    cmd = DRV_IOR(PCellShareProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_PORT_CELL_MIN_PROFILE_MIRROR, cmd, &ds);
    SetPCellShareProfile(V, shareThd_f, &ds, CTC_ASW_QOS_QUE_MIN_SHARE);
    cmd = DRV_IOW(PCellShareProfile_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_PORT_CELL_MIN_PROFILE_MIRROR, cmd, &ds);

    /* default ipg disable */
    for(i=0;i<(CTC_ASW_QOS_MAX_POLICER_ID + 1);i++)
    {
        cmd = DRV_IOR(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, i, cmd, &ds);
        SetIngressMeterCtrl(V, meterDelta_f, &ds,1);
        cmd = DRV_IOW(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,i, cmd, &ds);

        /*default config policer stats disable*/
        cmd = DRV_IOR(IngressCounterCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(i), cmd, &ds);
        SetIngressCounterCtrl(V, ctrl_f, &ds,CTC_ASW_QOS_POLICER_STATS_DISABLE);
        cmd = DRV_IOW(IngressCounterCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(i), cmd, &ds);
    }
    cmd = DRV_IOR(GlbMeterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, 0, cmd, &ds);
    SetGlbMeterCtrl(V, copyStcEn_f, &ds,1);
    cmd = DRV_IOW(GlbMeterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip,0, cmd, &ds);
    sal_memset(&user_define_cpu_reason[lchip], 0xFF, CTC_ASW_QOS_MAX_USER_DEFINE_REASON_NUM);

    return ret;
}

int32
ctc_asw_qos_deinit(uint8 lchip)
{
    return CTC_E_NONE;
}

int32
ctc_asw_qos_set_policer(uint8 lchip, ctc_qos_policer_t* p_policer)
{
    int32 ret = CTC_E_NONE;
    uint32 policer_id = 0;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 policer_mode = 0;
    uint32 pbs = 0;
    uint32 cbs = 0;
    uint32 cir = 0;
    uint32 pir = 0;
    IngressMeterCtrl_m ingress_meter_ctrl;
    ds_t ds;
    CTC_PTR_VALID_CHECK(p_policer);

    CTC_MAX_VALUE_CHECK(p_policer->policer.cir ,CTC_ASW_QOS_MAX_CHIP_PIR);
    CTC_MAX_VALUE_CHECK(p_policer->policer.pir ,CTC_ASW_QOS_MAX_CHIP_PIR);
    CTC_MAX_VALUE_CHECK(p_policer->policer.stats_mode ,CTC_ASW_QOS_POLICER_STATS_MODE_MAX);

    pbs = p_policer->policer.pbs;
    cbs = p_policer->policer.cbs;
    cir = p_policer->policer.cir;
    pir = p_policer->policer.pir;
    if (p_policer->policer.policer_mode == CTC_QOS_POLICER_MODE_RFC2697)
    {
        pir = 0;
    }
    else if (p_policer->policer.policer_mode == CTC_QOS_POLICER_MODE_RFC2698)
    {
        if (pir < cir)
        {
            return CTC_E_INVALID_CONFIG;
        }
        if (pbs < cbs)
        {
            return CTC_E_INVALID_CONFIG;
        }
    }
    else if (p_policer->policer.policer_mode == CTC_QOS_POLICER_MODE_STBM)
    {
        cir = pir;
        cbs = pbs;
        pir = 0;
        pbs = 0;
    }

    if (p_policer->enable)
    {
        /*TMA policer pbs/cbs data range is CTC_ASW_QOS_GLB_MIN_THREHOLD to CTC_ASW_QOS_GLB_SHAPE_THREHOLD*/
        CTC_VALUE_RANGE_CHECK(cbs<<1,CTC_ASW_QOS_GLB_MIN_THREHOLD,CTC_ASW_QOS_GLB_SHAPE_THREHOLD);
        if(p_policer->policer.policer_mode != CTC_QOS_POLICER_MODE_STBM)
        {
            CTC_VALUE_RANGE_CHECK(pbs<<1,CTC_ASW_QOS_GLB_MIN_THREHOLD,CTC_ASW_QOS_GLB_SHAPE_THREHOLD);
        }
    }

    if (p_policer->type == CTC_QOS_POLICER_TYPE_PORT)
    {
        CTC_MAX_GPORT_CHECK(p_policer->id.gport);
        CTC_ERROR_RETURN(ctc_asw_port_get_direction_property(lchip, p_policer->id.gport,CTC_PORT_DIR_PROP_PORT_POLICER_VALID,p_policer->dir,&value));
        value = value&0xff;
        if (value)
        {
           CTC_ERROR_RETURN(_ctc_asw_port_get_internal_property(lchip, p_policer->id.gport,CTC_PORT_INT_PROP_INGRESS_POLICER_PTR,&policer_id));
        }

        if (p_policer->enable && (0 == value))
        {
           CTC_ERROR_RETURN(_ctc_asw_bitmap_alloc(lchip,policer_bitmap[lchip],0,(CTC_ASW_QOS_MAX_POLICER_ID+1),&policer_id));
           /*set port policer enable*/
           CTC_ERROR_RETURN(ctc_asw_port_set_direction_property(lchip, p_policer->id.gport,CTC_PORT_DIR_PROP_PORT_POLICER_VALID,p_policer->dir,p_policer->enable));
           /*set port policer ptr*/
           CTC_ERROR_RETURN(_ctc_asw_port_set_internal_property(lchip, p_policer->id.gport,CTC_PORT_INT_PROP_INGRESS_POLICER_PTR,policer_id));
        }
        else if ((0 == p_policer->enable) && (0 == value))
        {
            return CTC_E_NOT_EXIST;
        }
        else if ((0 == p_policer->enable) && (1 == value))
        {
           CTC_ERROR_RETURN(_ctc_asw_bitmap_free(lchip,policer_bitmap[lchip],policer_id));
           /*set port policer down*/
           CTC_ERROR_RETURN(ctc_asw_port_set_direction_property(lchip, p_policer->id.gport,CTC_PORT_DIR_PROP_PORT_POLICER_VALID,p_policer->dir,p_policer->enable));
        }
    }
    else if (p_policer->type == CTC_QOS_POLICER_TYPE_FLOW)
    {
        if((p_policer->id.policer_id != 0) && (p_policer->enable))
        {
             CTC_MAX_VALUE_CHECK(p_policer->id.policer_id,CTC_ASW_QOS_MAX_POLICER_ID);
             policer_id = p_policer->id.policer_id;
             if(CTC_E_NONE == _ctc_asw_bitmap_check_active(lchip,policer_bitmap[lchip],policer_id))
             {
                 return CTC_E_NOT_EXIST;
             }
        }
        else if((p_policer->enable) && (p_policer->id.policer_id == 0))
        {
            CTC_ERROR_RETURN(_ctc_asw_bitmap_alloc(lchip,policer_bitmap[lchip],1,(CTC_ASW_QOS_MAX_POLICER_ID+1),&policer_id));
            p_policer->id.policer_id = policer_id;
        }
        else if ((0 == p_policer->enable) && (p_policer->id.policer_id != 0))
        {
            CTC_MAX_VALUE_CHECK(p_policer->id.policer_id,CTC_ASW_QOS_MAX_POLICER_ID);
            policer_id = p_policer->id.policer_id;
            CTC_ERROR_RETURN(_ctc_asw_bitmap_free(lchip,policer_bitmap[lchip],policer_id));
            p_policer->id.policer_id = 0;
        }
        else if ((0 == p_policer->enable) && (p_policer->id.policer_id == 0))
        {
            return CTC_E_NOT_EXIST;
        }
    }
    CTC_API_LOCK(lchip);
    cmd = DRV_IOR(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, policer_id, cmd, &ingress_meter_ctrl);
    policer_mode = (p_policer->policer.policer_mode == CTC_QOS_POLICER_MODE_STBM) ? 0 : (p_policer->policer.policer_mode-1);
    SetIngressMeterCtrl(V, meterMode_f, &ingress_meter_ctrl,policer_mode);
    SetIngressMeterCtrl(V, cm_f, &ingress_meter_ctrl, p_policer->policer.is_color_aware ? 0:1);
    SetIngressMeterCtrl(V, dropMode_f, &ingress_meter_ctrl,p_policer->policer.drop_color);
    SetIngressMeterCtrl(V, b0Freshcount_f, &ingress_meter_ctrl,(cir>>3));
    SetIngressMeterCtrl(V, b0Bucketsize_f, &ingress_meter_ctrl,(cbs<<1));
    SetIngressMeterCtrl(V, b1Freshcount_f, &ingress_meter_ctrl,(pir>>3));
    SetIngressMeterCtrl(V, b1Bucketsize_f, &ingress_meter_ctrl,(pbs<<1));
    SetIngressMeterCtrl(V, meterEn_f, &ingress_meter_ctrl,(p_policer->enable ? 1:0));
    cmd = DRV_IOW(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip,policer_id, cmd, &ingress_meter_ctrl);

    /*set policer stats*/
    cmd = DRV_IOR(IngressCounterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(policer_id), cmd, &ds);
    if (p_policer->policer.stats_en)
    {
        value = (p_policer->policer.stats_mode == 0)?CTC_ASW_QOS_POLICER_STATS_COLOR_AWARE:CTC_ASW_QOS_POLICER_STATS_COLOR_BLIND;
    }
    else
    {
        value = CTC_ASW_QOS_POLICER_STATS_DISABLE;
    }
    SetIngressCounterCtrl(V, ctrl_f, &ds,value);
    cmd = DRV_IOW(IngressCounterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(policer_id), cmd, &ds);
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_get_policer(uint8 lchip, ctc_qos_policer_t* p_policer)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    uint32 value = 0;
    uint32 policer_id = 0;
    IngressMeterCtrl_m ingress_meter_ctrl;
    ds_t ds;
    CTC_PTR_VALID_CHECK(p_policer);

    CTC_ERROR_RETURN(_ctc_asw_qos_check_and_get_policer_id(lchip, p_policer->type, p_policer->id.policer_id, p_policer->id.gport, &policer_id));
 
    CTC_API_LOCK(lchip);
    cmd = DRV_IOR(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, policer_id, cmd, &ingress_meter_ctrl);
    value = GetIngressMeterCtrl(V, meterMode_f, &ingress_meter_ctrl);
    p_policer->policer.policer_mode = value+1;
    value = GetIngressMeterCtrl(V, cm_f, &ingress_meter_ctrl);
    p_policer->policer.is_color_aware = value ? 0:1;
    p_policer->policer.drop_color = GetIngressMeterCtrl(V, dropMode_f, &ingress_meter_ctrl);
    value = GetIngressMeterCtrl(V, b0Freshcount_f, &ingress_meter_ctrl);
    p_policer->policer.cir = value <<3;
    value = GetIngressMeterCtrl(V, b0Bucketsize_f, &ingress_meter_ctrl);
    p_policer->policer.cbs = value>>1;
    value = GetIngressMeterCtrl(V, b1Freshcount_f, &ingress_meter_ctrl);
    p_policer->policer.pir = value <<3;
    value = GetIngressMeterCtrl(V, b1Bucketsize_f, &ingress_meter_ctrl);
    p_policer->policer.pbs = value>>1;

    /*get policer stats*/
    cmd = DRV_IOR(IngressCounterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret ? ret : DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(policer_id), cmd, &ds);
    value = GetIngressCounterCtrl(V, ctrl_f, &ds);
    if (value == CTC_ASW_QOS_POLICER_STATS_DISABLE)
    {
        p_policer->policer.stats_en = 0;
    }
    else
    {
        p_policer->policer.stats_mode = (value == CTC_ASW_QOS_POLICER_STATS_COLOR_AWARE )?0:1;
        p_policer->policer.stats_en = 1;
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}


/**
 @brief set domain map

 @param[in]  ctc_qos_domain_map_t  qos domain param

 @return CTC_E_XXX

*/
int32
ctc_asw_qos_set_domain_map(uint8 lchip, ctc_qos_domain_map_t* p_domain_map)
{
    int32 ret = CTC_E_NONE;
    uint8 domain      = 0;
    uint8 cos         = 0;
    uint8 dscp        = 0;
    uint8 cfi         = 0;
    uint8 priority    = 0;
    uint8 color       = 0;
    uint32 cmd        = 0;
    uint32 tbl_index  = 0;
    uint32 value      = 0;
    PriLplcMapTable_m  pri_lplc_map_table;
    LplcPriMapTable_m  lplc_pri_map_table;
    CTC_PTR_VALID_CHECK(p_domain_map);
    domain   = p_domain_map->domain_id;
    priority = p_domain_map->priority;
    CTC_MAX_VALUE_CHECK(domain,7);
    CTC_MAX_VALUE_CHECK(priority,15);
    CTC_MAX_VALUE_CHECK(p_domain_map->color, SYS_QOS_CLASS_COLOR_MAX);

    if (p_domain_map->color == CTC_QOS_COLOR_GREEN )
    {
        color = 0;
    }
    else if (p_domain_map->color == CTC_QOS_COLOR_YELLOW)
    {
        color = 1;
    }
    else if (p_domain_map->color == CTC_QOS_COLOR_RED)
    {
        color = 2;
    }
    else
    {
        color = 3;
    }
    CTC_API_LOCK(lchip);
    if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_IGS_COS_TO_PRI_COLOR)
    {
        cos = p_domain_map->hdr_pri.dot1p.cos;
        cfi = p_domain_map->hdr_pri.dot1p.dei;
        CTC_MAX_VALUE_CHECK_UNLOCK(cos, SYS_QOS_CLASS_COS_MAX);
        CTC_MAX_VALUE_CHECK_UNLOCK(cfi, SYS_QOS_CLASS_CFI_MAX);
        sal_memset(&pri_lplc_map_table, 0, sizeof(PriLplcMapTable_m));
        tbl_index = (domain << 6) | (3 << 4) | (cos << 1) | cfi;
        cmd = DRV_IOR(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &pri_lplc_map_table);
        SetPriLplcMapTable(V, localPri_f, &pri_lplc_map_table, priority);
        SetPriLplcMapTable(V, localColor_f, &pri_lplc_map_table, color);
        cmd = DRV_IOW(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &pri_lplc_map_table);
    }
    else if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_IGS_DSCP_TO_PRI_COLOR)
    {
        dscp = p_domain_map->hdr_pri.tos.dscp;
        CTC_MAX_VALUE_CHECK_UNLOCK(dscp, SYS_QOS_CLASS_DSCP_MAX);
        sal_memset(&pri_lplc_map_table, 0, sizeof(PriLplcMapTable_m));
        domain = domain | 0x8;
        tbl_index = (domain << 6) | dscp;
        cmd = DRV_IOR(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &pri_lplc_map_table);

        SetPriLplcMapTable(V, localPri_f, &pri_lplc_map_table, priority);
        SetPriLplcMapTable(V, localColor_f, &pri_lplc_map_table, color);
        cmd = DRV_IOW(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &pri_lplc_map_table);
    }
    else if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_EGS_PRI_COLOR_TO_COS)
    {
        cos = p_domain_map->hdr_pri.dot1p.cos;
        cfi = p_domain_map->hdr_pri.dot1p.dei;
        CTC_MAX_VALUE_CHECK_UNLOCK(cos, SYS_QOS_CLASS_COS_MAX);
        CTC_MAX_VALUE_CHECK_UNLOCK(cfi, SYS_QOS_CLASS_CFI_MAX);
        sal_memset(&lplc_pri_map_table, 0, sizeof(LplcPriMapTable_m));
        tbl_index = (domain << 6) | (priority << 2) | color ;
        cmd = DRV_IOR(LplcPriMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &lplc_pri_map_table);
        value = (cos << 1 | cfi);
        SetLplcPriMapTable(V,scos_f,&lplc_pri_map_table,value);
        cmd = DRV_IOW(LplcPriMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &lplc_pri_map_table);
    }
    else if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_EGS_PRI_COLOR_TO_DSCP)
    {
        dscp = p_domain_map->hdr_pri.tos.dscp;
        CTC_MAX_VALUE_CHECK_UNLOCK(dscp, SYS_QOS_CLASS_DSCP_MAX);
        sal_memset(&lplc_pri_map_table, 0, sizeof(LplcPriMapTable_m));
        domain = domain | 0x8;
        tbl_index = (domain << 6) | (priority << 2) | color ;
        cmd = DRV_IOR(LplcPriMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &lplc_pri_map_table);
        SetLplcPriMapTable(V,dscp_f,&lplc_pri_map_table,dscp);
        cmd = DRV_IOW(LplcPriMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, tbl_index, cmd, &lplc_pri_map_table);
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

/**
 @brief get domain map

 @param[in]  ctc_qos_domain_map_t  qos domain param

 @return CTC_E_XXX

*/
int32
ctc_asw_qos_get_domain_map(uint8 lchip, ctc_qos_domain_map_t* p_domain_map)
{
    int32 ret = CTC_E_NONE;
    uint8 domain   = 0;
    uint8 cos      = 0;
    uint8 dscp     = 0;
    uint8 cfi      = 0;
    uint8 priority = 0;
    uint8 color    = 0;
    uint32 tbl_index  = 0;
    uint32 value      = 0;
    uint32 cmd        = 0;
    PriLplcMapTable_m  pri_lplc_map_table;
    LplcPriMapTable_m  lplc_pri_map_table;

    CTC_PTR_VALID_CHECK(p_domain_map);
    CTC_MAX_VALUE_CHECK(p_domain_map->domain_id,7);
    CTC_MAX_VALUE_CHECK(p_domain_map->priority,15);
    CTC_MAX_VALUE_CHECK(p_domain_map->color, SYS_QOS_CLASS_COLOR_MAX);

    if (p_domain_map->color == CTC_QOS_COLOR_GREEN )
    {
        color = 0;
    }
    else if (p_domain_map->color == CTC_QOS_COLOR_YELLOW)
    {
        color = 1;
    }
    else if (p_domain_map->color == CTC_QOS_COLOR_RED)
    {
        color = 2;
    }
    else
    {
        color = 3;
    }

    CTC_API_LOCK(lchip);
    domain = p_domain_map->domain_id;
    if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_IGS_COS_TO_PRI_COLOR)
    {
        cos = p_domain_map->hdr_pri.dot1p.cos;
        cfi = p_domain_map->hdr_pri.dot1p.dei;
        CTC_MAX_VALUE_CHECK_UNLOCK(cos, SYS_QOS_CLASS_COS_MAX);
        CTC_MAX_VALUE_CHECK_UNLOCK(cfi, SYS_QOS_CLASS_CFI_MAX);
        sal_memset(&pri_lplc_map_table, 0, sizeof(PriLplcMapTable_m));
        tbl_index = (domain << 6) | (3 << 4) | (cos << 1) | cfi;
        cmd = DRV_IOR(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &pri_lplc_map_table);
        p_domain_map->priority = GetPriLplcMapTable(V, localPri_f, &pri_lplc_map_table);
        value = GetPriLplcMapTable(V, localColor_f, &pri_lplc_map_table);
        p_domain_map->color = ((value == 0) ? CTC_QOS_COLOR_GREEN : ((value == 1) ? CTC_QOS_COLOR_YELLOW : 
        CTC_QOS_COLOR_RED));
    }
    else if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_IGS_DSCP_TO_PRI_COLOR)
    {
        dscp = p_domain_map->hdr_pri.tos.dscp;
        CTC_MAX_VALUE_CHECK_UNLOCK(dscp, SYS_QOS_CLASS_DSCP_MAX);
        sal_memset(&pri_lplc_map_table, 0, sizeof(PriLplcMapTable_m));
        domain = domain | 0x8;
        tbl_index = (domain << 6) | dscp;
        cmd = DRV_IOR(PriLplcMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &pri_lplc_map_table);

        p_domain_map->priority = GetPriLplcMapTable(V, localPri_f, &pri_lplc_map_table);
        value = GetPriLplcMapTable(V, localColor_f, &pri_lplc_map_table);
        p_domain_map->color = ((value == 0) ? CTC_QOS_COLOR_GREEN : ((value == 1) ? CTC_QOS_COLOR_YELLOW : 
        CTC_QOS_COLOR_RED));
    }
    else if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_EGS_PRI_COLOR_TO_COS)
    {
        priority = p_domain_map->priority;
        sal_memset(&lplc_pri_map_table, 0, sizeof(LplcPriMapTable_m));
        tbl_index = (domain << 6) | (priority << 2) | color ;
        cmd = DRV_IOR(LplcPriMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &lplc_pri_map_table);
        value = GetLplcPriMapTable(V,scos_f,&lplc_pri_map_table);
        p_domain_map->hdr_pri.dot1p.cos = ((value & 0xE) >> 1);
        p_domain_map->hdr_pri.dot1p.dei = (value & 0x1);

    }
    else if (p_domain_map->type == CTC_QOS_DOMAIN_MAP_EGS_PRI_COLOR_TO_DSCP)
    {
        priority = p_domain_map->priority;
        sal_memset(&lplc_pri_map_table, 0, sizeof(LplcPriMapTable_m));
        domain = domain | 0x8;
        tbl_index = (domain << 6) | (priority << 2) | color ;
        cmd = DRV_IOR(LplcPriMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, tbl_index, cmd, &lplc_pri_map_table);
        p_domain_map->hdr_pri.tos.dscp = GetLplcPriMapTable(V,dscp_f,&lplc_pri_map_table);
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_set_global_config(uint8 lchip, ctc_qos_glb_cfg_t* p_glb_cfg)
{
    int32 ret    = CTC_E_NONE;
    uint32 cmd   = 0;
    uint32 i   = 0;
    uint32 value   = 0;
    IngressMeterCtrl_m ingress_meter_ctrl;
    SchGlbMode_m      sch_glb_mode;
    CTC_PTR_VALID_CHECK(p_glb_cfg);

    CTC_API_LOCK(lchip);
    value = p_glb_cfg->u.value ? 1 : 0;
    if (p_glb_cfg->cfg_type == CTC_QOS_GLB_CFG_POLICER_IPG_EN)
    {
        for(i=0;i<(CTC_ASW_QOS_MAX_POLICER_ID + 1);i++)
        {
            cmd = DRV_IOR(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, i, cmd, &ingress_meter_ctrl);
            SetIngressMeterCtrl(V, meterDelta_f, &ingress_meter_ctrl, value);
            cmd = DRV_IOW(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip,i, cmd, &ingress_meter_ctrl);
        }
    }
    else if (p_glb_cfg->cfg_type == CTC_QOS_GLB_CFG_SHAPE_IPG_EN)
    {
        cmd = DRV_IOR(SchGlbMode_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &sch_glb_mode);
        SetSchGlbMode(V, minMaxIfgBytes_f, &sch_glb_mode, value ? CTC_ASW_QOS_SHAPE_IPG_DEFAULT:CTC_ASW_QOS_SHAPE_IPG_MIN);
        SetSchGlbMode(V, ifgBytes_f, &sch_glb_mode, value ? CTC_ASW_QOS_SHAPE_IPG_DEFAULT:CTC_ASW_QOS_SHAPE_IPG_MIN);
        cmd = DRV_IOW(SchGlbMode_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,0, cmd, &sch_glb_mode);
    }

    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_get_global_config(uint8 lchip, ctc_qos_glb_cfg_t* p_glb_cfg)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint32 value   = 0;
    IngressMeterCtrl_m ingress_meter_ctrl;
    SchGlbMode_m      sch_glb_mode;
    CTC_PTR_VALID_CHECK(p_glb_cfg);
    CTC_API_LOCK(lchip);
    if (p_glb_cfg->cfg_type == CTC_QOS_GLB_CFG_POLICER_IPG_EN)
    {
        cmd = DRV_IOR(IngressMeterCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 1, cmd, &ingress_meter_ctrl);
        p_glb_cfg->u.value = GetIngressMeterCtrl(V, meterDelta_f, &ingress_meter_ctrl);
    }
    else if (p_glb_cfg->cfg_type == CTC_QOS_GLB_CFG_SHAPE_IPG_EN)
    {
        cmd = DRV_IOR(SchGlbMode_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &sch_glb_mode);
        value = GetSchGlbMode(V, minMaxIfgBytes_f, &sch_glb_mode);
        p_glb_cfg->u.value = (CTC_ASW_QOS_SHAPE_IPG_DEFAULT == value)? 1:0;
    }
    CTC_API_UNLOCK(lchip);

    return ret;
}

/*resrc*/
int32
ctc_asw_qos_set_resrc(uint8 lchip, ctc_qos_resrc_t* p_resrc)
{
    int32  ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint8  profile_id  = 0;
    IngMmuPortCtrl_m ing_mmu_port_ctrl;
    PCellMinProfile_m  p_cell_min_profile;

    CTC_PTR_VALID_CHECK(p_resrc);

    sal_memset(&ing_mmu_port_ctrl, 0, sizeof(ing_mmu_port_ctrl));
    sal_memset(&p_cell_min_profile, 0, sizeof(p_cell_min_profile));

    CTC_API_LOCK(lchip);
    switch (p_resrc->cfg_type)
    {
    case CTC_QOS_RESRC_CFG_PORT_MIN:
        p_resrc->u.port_min.gport = CTC_MAP_GPORT_TO_LPORT(p_resrc->u.port_min.gport);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.port_min.gport, CTC_ASW_MAX_PHY_PORT);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.port_min.threshold, CTC_ASW_QOS_FLOW_CTRL_THRESHOLD);
        if ((CTC_INGRESS == p_resrc->u.port_min.dir) || (CTC_BOTH_DIRECTION == p_resrc->u.port_min.dir))
        {
            cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, p_resrc->u.port_min.gport, cmd, &ing_mmu_port_ctrl);
            SetIngMmuPortCtrl(V, cellMin_f, &ing_mmu_port_ctrl,(p_resrc->u.port_min.threshold>>3));
            cmd = DRV_IOW(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip,p_resrc->u.port_min.gport, cmd, &ing_mmu_port_ctrl);
        }
        if ((CTC_EGRESS == p_resrc->u.port_min.dir) || (CTC_BOTH_DIRECTION == p_resrc->u.port_min.dir))
        {
            SetPCellMinProfile(V,minThd_f,&p_cell_min_profile,(p_resrc->u.port_min.threshold>>3));
            cmd = DRV_IOW(PCellMinProfile_t, DRV_ENTRY_FLAG);
            ret = ret ? ret : DRV_IOCTL(lchip, profile_id, cmd, &p_cell_min_profile);
        }
        break;

    case CTC_QOS_RESRC_CFG_FLOW_CTL:
        p_resrc->u.flow_ctl.gport = CTC_MAP_GPORT_TO_LPORT(p_resrc->u.flow_ctl.gport);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.flow_ctl.gport, CTC_ASW_MAX_PHY_PORT);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.flow_ctl.drop_thrd,CTC_ASW_QOS_FLOW_CTRL_THRESHOLD);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.flow_ctl.xon_thrd,CTC_ASW_QOS_FLOW_CTRL_THRESHOLD);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.flow_ctl.xoff_thrd,CTC_ASW_QOS_FLOW_CTRL_THRESHOLD);
        if (p_resrc->u.flow_ctl.xon_thrd > p_resrc->u.flow_ctl.xoff_thrd)
        {
            CTC_API_UNLOCK(lchip);
            return CTC_E_INVALID_CONFIG;
        }
        p_resrc->u.flow_ctl.xon_thrd = p_resrc->u.flow_ctl.xoff_thrd - p_resrc->u.flow_ctl.xon_thrd;
        cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_resrc->u.flow_ctl.gport, cmd, &ing_mmu_port_ctrl);
        SetIngMmuPortCtrl(V, cellHead_f, &ing_mmu_port_ctrl,p_resrc->u.flow_ctl.drop_thrd>>3);
        SetIngMmuPortCtrl(V, cellOffset_f, &ing_mmu_port_ctrl,p_resrc->u.flow_ctl.xon_thrd>>3);
        SetIngMmuPortCtrl(V, cellShare_f, &ing_mmu_port_ctrl,p_resrc->u.flow_ctl.xoff_thrd>>3);
        SetIngMmuPortCtrl(V, cellDynamic_f, &ing_mmu_port_ctrl,0);
        cmd = DRV_IOW(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,p_resrc->u.flow_ctl.gport, cmd, &ing_mmu_port_ctrl);
        break;

    default:
        CTC_API_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_get_resrc(uint8 lchip, ctc_qos_resrc_t* p_resrc)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint8  profile_id  = 0;
    uint32 value   = 0;
    IngMmuPortCtrl_m   ing_mmu_port_ctrl;
    PCellMinProfile_m  p_cell_min_profile;

    CTC_PTR_VALID_CHECK(p_resrc);

    CTC_API_LOCK(lchip);
    switch (p_resrc->cfg_type)
    {
    case CTC_QOS_RESRC_CFG_PORT_MIN:
        p_resrc->u.port_min.gport = CTC_MAP_GPORT_TO_LPORT(p_resrc->u.port_min.gport);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.port_min.gport, CTC_ASW_MAX_PHY_PORT);
        if (CTC_INGRESS == p_resrc->u.port_min.dir)
        {
            cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, p_resrc->u.port_min.gport, cmd, &ing_mmu_port_ctrl);
            value = GetIngMmuPortCtrl(V, cellMin_f, &ing_mmu_port_ctrl);
            p_resrc->u.port_min.threshold = value<<3;
        }
        if (CTC_EGRESS == p_resrc->u.port_min.dir)
        {
            cmd = DRV_IOR(PCellMinProfile_t, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, profile_id, cmd, &p_cell_min_profile);
            value = GetPCellMinProfile(V,minThd_f,&p_cell_min_profile);
            p_resrc->u.port_min.threshold = value<<3;
        }
        break;

    case CTC_QOS_RESRC_CFG_FLOW_CTL:
        p_resrc->u.flow_ctl.gport = CTC_MAP_GPORT_TO_LPORT(p_resrc->u.flow_ctl.gport);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_resrc->u.flow_ctl.gport, CTC_ASW_MAX_PHY_PORT);
        cmd = DRV_IOR(IngMmuPortCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_resrc->u.flow_ctl.gport, cmd, &ing_mmu_port_ctrl);
        value = GetIngMmuPortCtrl(V, cellHead_f, &ing_mmu_port_ctrl);
        p_resrc->u.flow_ctl.drop_thrd = 8 * value;
        value = GetIngMmuPortCtrl(V, cellShare_f, &ing_mmu_port_ctrl);
        p_resrc->u.flow_ctl.xoff_thrd = 8 * value;
        value = GetIngMmuPortCtrl(V, cellOffset_f, &ing_mmu_port_ctrl);
        p_resrc->u.flow_ctl.xon_thrd  = p_resrc->u.flow_ctl.xoff_thrd - (8 * value);

        break;

    default:
        CTC_API_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

/*shape*/
int32
ctc_asw_qos_set_shape(uint8 lchip, ctc_qos_shape_t* p_shape)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint32 queue_id  = 0;
    uint32 value   = 0;
    PortShape_m port_shape;
    QueueMinMax_m queue_min_max;

    CTC_PTR_VALID_CHECK(p_shape);
    if (p_shape->type == CTC_QOS_SHAPE_PORT)
    {
        CTC_MAX_GPORT_CHECK(p_shape->shape.port_shape.gport);
    }
    else
    {
        CTC_MAX_GPORT_CHECK(p_shape->shape.queue_shape.queue.gport);
        CTC_MAX_VALUE_CHECK(p_shape->shape.queue_shape.queue.queue_id,(p_shape->shape.queue_shape.queue.gport ==
        _ctc_asw_chip_get_cpu_port(lchip)) ? CTC_ASW_QOS_MAX_CPU_QUE_ID:CTC_ASW_QOS_MAX_QUE_ID);
    }

    CTC_API_LOCK(lchip);
    switch(p_shape->type)
    {
    case CTC_QOS_SHAPE_PORT:
        cmd = DRV_IOR(PortShape_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_shape->shape.port_shape.gport, cmd, &port_shape);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.port_shape.pbs,CTC_ASW_QOS_MAX_CHIP_PBS);
        if (p_shape->shape.port_shape.pps_en)
        {
            CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.port_shape.pir,CTC_ASW_QOS_MAX_CHIP_PPS_PIR);
            SetPortShape(V,meterMode_f,&port_shape,1);
            SetPortShape(V,maxRefreshCnt_f,&port_shape,p_shape->shape.port_shape.pir);
            if (p_shape->shape.port_shape.pbs)
            {
                SetPortShape(V,maxThreshold_f,&port_shape,(p_shape->shape.port_shape.pbs<<1));
            }
            else
            {
                value = (((p_shape->shape.port_shape.pir + 1)<<1) > CTC_ASW_QOS_GLB_SHAPE_THREHOLD) ?  CTC_ASW_QOS_GLB_SHAPE_THREHOLD : ((p_shape->shape.port_shape.pir + 1)<<1);
                SetPortShape(V,maxThreshold_f,&port_shape,value);
            }
        }
        else
        {
            CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.port_shape.pir,CTC_ASW_QOS_MAX_CHIP_PBS_PIR);
            SetPortShape(V,meterMode_f,&port_shape,0);
            SetPortShape(V,maxRefreshCnt_f,&port_shape,(p_shape->shape.port_shape.pir>>3));
            if (p_shape->shape.port_shape.pbs)
            {
                SetPortShape(V,maxThreshold_f,&port_shape,(p_shape->shape.port_shape.pbs<<1));
            }
            else
            {
                value = (((p_shape->shape.port_shape.pir>>2)+1) > CTC_ASW_QOS_GLB_SHAPE_THREHOLD) ?   CTC_ASW_QOS_GLB_SHAPE_THREHOLD : ((p_shape->shape.port_shape.pir>>2)+1);
                SetPortShape(V,maxThreshold_f,&port_shape,value);
            }
        }
        SetPortShape(V,maxMeterEn_f,&port_shape,p_shape->shape.port_shape.enable);
        cmd = DRV_IOW(PortShape_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, p_shape->shape.port_shape.gport, cmd, &port_shape);
        break;

    case CTC_QOS_SHAPE_QUEUE:
        if (p_shape->shape.queue_shape.pir < p_shape->shape.queue_shape.cir)
        {
            CTC_API_UNLOCK(lchip);
            return CTC_E_INVALID_CONFIG;
        }
        p_shape->shape.queue_shape.cir = (p_shape->shape.queue_shape.pir == 0) ? p_shape->shape.queue_shape.pir : p_shape->shape.queue_shape.cir;
        queue_id = (p_shape->shape.queue_shape.queue.gport <<3) + p_shape->shape.queue_shape.queue.queue_id;
        cmd = DRV_IOR(QueueMinMax_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, queue_id, cmd, &queue_min_max);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.queue_shape.pbs,CTC_ASW_QOS_MAX_CHIP_PBS);
        CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.queue_shape.cbs,CTC_ASW_QOS_MAX_CHIP_PBS);
        if (p_shape->shape.queue_shape.pps_en)
        {
            CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.queue_shape.pir,CTC_ASW_QOS_MAX_CHIP_PPS_PIR);
            CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.queue_shape.cir,CTC_ASW_QOS_MAX_CHIP_PPS_PIR);
            SetQueueMinMax(V,meterMode_f,&queue_min_max,1);
            SetQueueMinMax(V,maxRefreshCnt_f,&queue_min_max,p_shape->shape.queue_shape.pir);
            SetQueueMinMax(V,minRefreshCnt_f,&queue_min_max,p_shape->shape.queue_shape.cir);
            SetQueueMinMax(V,maxThreshold_f,&queue_min_max,p_shape->shape.queue_shape.pbs? (p_shape->shape.queue_shape.pbs<<1) : CTC_ASW_QOS_GLB_SHAPE_THREHOLD);
            SetQueueMinMax(V,minThreshold_f,&queue_min_max,p_shape->shape.queue_shape.cbs? (p_shape->shape.queue_shape.cbs<<1) : CTC_ASW_QOS_GLB_SHAPE_THREHOLD);
        }
        else
        {
            CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.queue_shape.pir,CTC_ASW_QOS_MAX_CHIP_PBS_PIR);
            CTC_MAX_VALUE_CHECK_UNLOCK(p_shape->shape.queue_shape.cir,CTC_ASW_QOS_MAX_CHIP_PBS_PIR);
            SetQueueMinMax(V,meterMode_f,&queue_min_max,0);
            SetQueueMinMax(V,maxRefreshCnt_f,&queue_min_max,p_shape->shape.queue_shape.pir>>3);
            SetQueueMinMax(V,minRefreshCnt_f,&queue_min_max,p_shape->shape.queue_shape.cir>>3);
            SetQueueMinMax(V,maxThreshold_f,&queue_min_max,p_shape->shape.queue_shape.pbs? (p_shape->shape.queue_shape.pbs<<1) :CTC_ASW_QOS_GLB_SHAPE_THREHOLD);
            SetQueueMinMax(V,minThreshold_f,&queue_min_max,p_shape->shape.queue_shape.cbs? (p_shape->shape.queue_shape.cbs<<1) :CTC_ASW_QOS_GLB_SHAPE_THREHOLD);
        }
        SetQueueMinMax(V,maxMeterEn_f,&queue_min_max,p_shape->shape.queue_shape.enable);
        SetQueueMinMax(V,minMeterEn_f,&queue_min_max,p_shape->shape.queue_shape.enable);
        cmd = DRV_IOW(QueueMinMax_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, queue_id, cmd, &queue_min_max);
        break;

    default:
        CTC_API_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;
    }

    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_get_shape(uint8 lchip, ctc_qos_shape_t* p_shape)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint32 queue_id  = 0;
    uint32 value  = 0;
    PortShape_m port_shape;
    QueueMinMax_m queue_min_max;

    CTC_PTR_VALID_CHECK(p_shape);
    if (p_shape->type == CTC_QOS_SHAPE_PORT)
    {
        CTC_MAX_GPORT_CHECK(p_shape->shape.port_shape.gport);
    }
    else
    {
        CTC_MAX_GPORT_CHECK(p_shape->shape.queue_shape.queue.gport);
        CTC_MAX_VALUE_CHECK(p_shape->shape.queue_shape.queue.queue_id,(p_shape->shape.queue_shape.queue.gport == 
        _ctc_asw_chip_get_cpu_port(lchip)) ? CTC_ASW_QOS_MAX_CPU_QUE_ID:CTC_ASW_QOS_MAX_QUE_ID);
    }


    CTC_API_LOCK(lchip);
    switch(p_shape->type)
    {
    case CTC_QOS_SHAPE_PORT:
        cmd = DRV_IOR(PortShape_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_shape->shape.port_shape.gport, cmd, &port_shape);
        if (p_shape->shape.port_shape.pps_en)
        {
            value = GetPortShape(V,maxRefreshCnt_f,&port_shape);
            p_shape->shape.port_shape.pir = value;
            value = GetPortShape(V,maxThreshold_f,&port_shape);
            p_shape->shape.port_shape.pbs = value>>1;
        }
        else
        {
            value = GetPortShape(V,maxRefreshCnt_f,&port_shape);
            p_shape->shape.port_shape.pir = value<<3;
            value = GetPortShape(V,maxThreshold_f,&port_shape);
            p_shape->shape.port_shape.pbs = value>>1;
        }
        p_shape->shape.port_shape.enable = GetPortShape(V,maxMeterEn_f,&port_shape);
        break;

    case CTC_QOS_SHAPE_QUEUE:
        queue_id = (p_shape->shape.queue_shape.queue.gport <<3) + p_shape->shape.queue_shape.queue.queue_id;
        cmd = DRV_IOR(QueueMinMax_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, queue_id, cmd, &queue_min_max);
        if (p_shape->shape.queue_shape.pps_en)
        {
            p_shape->shape.queue_shape.pir = GetQueueMinMax(V,maxRefreshCnt_f,&queue_min_max);
            p_shape->shape.queue_shape.cir = GetQueueMinMax(V,minRefreshCnt_f,&queue_min_max);
            value = GetQueueMinMax(V,maxThreshold_f,&queue_min_max);
            p_shape->shape.queue_shape.pbs =  value>>1;
            value = GetQueueMinMax(V,minThreshold_f,&queue_min_max);
            p_shape->shape.queue_shape.cbs =  value>>1;

        }
        else
        {
            value = GetQueueMinMax(V,maxRefreshCnt_f,&queue_min_max);
            p_shape->shape.queue_shape.pir = value<<3;
            value = GetQueueMinMax(V,minRefreshCnt_f,&queue_min_max);
            p_shape->shape.queue_shape.cir = value<<3;
            value = GetQueueMinMax(V,maxThreshold_f,&queue_min_max);
            p_shape->shape.queue_shape.pbs = value>>1;
            value = GetQueueMinMax(V,minThreshold_f,&queue_min_max);
            p_shape->shape.queue_shape.cbs = value>>1;
        }
        p_shape->shape.queue_shape.enable =  GetQueueMinMax(V,maxMeterEn_f,&queue_min_max);
        break;

    default:
        CTC_API_UNLOCK(lchip);
        return CTC_E_INVALID_PARAM;

    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_set_sched(uint8 lchip, ctc_qos_sched_t* p_sched)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint8 value  = 0;
    uint32 queue_id  = 0;
    SchPortMode_m sch_port_mode;
    QueueWeight_m  queue_weight;
    CTC_PTR_VALID_CHECK(p_sched);
    CTC_MAX_VALUE_CHECK(p_sched->sched.queue_sched.queue.queue_id,CTC_ASW_QOS_MAX_QUE_ID);
    CTC_MAX_GPORT_CHECK(p_sched->sched.queue_sched.queue.gport);
    CTC_MAX_VALUE_CHECK(p_sched->sched.queue_sched.exceed_weight,CTC_ASW_QOS_MAX_WEIGHT);

    CTC_API_LOCK(lchip);
    queue_id = (p_sched->sched.queue_sched.queue.gport<<3) + p_sched->sched.queue_sched.queue.queue_id;

    if (p_sched->sched.queue_sched.cfg_type == CTC_QOS_SCHED_CFG_EXCEED_CLASS)
    {
        cmd = DRV_IOR(SchPortMode_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_sched->sched.queue_sched.queue.gport, cmd, &sch_port_mode);
        value = GetSchPortMode(V,spBitmap_f,&sch_port_mode);
        CTC_BIT_SET(value,p_sched->sched.queue_sched.queue.queue_id);
        SetSchPortMode(V,spBitmap_f,&sch_port_mode,value);
        cmd = DRV_IOW(SchPortMode_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, p_sched->sched.queue_sched.queue.gport, cmd, &sch_port_mode);

        cmd = DRV_IOR(QueueWeight_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, queue_id, cmd, &queue_weight);
        SetQueueWeight(V,weight_f,&queue_weight,1);
        cmd = DRV_IOW(QueueWeight_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,queue_id, cmd, &queue_weight);
    }
    if (p_sched->sched.queue_sched.cfg_type == CTC_QOS_SCHED_CFG_EXCEED_WEIGHT)
    {
        cmd = DRV_IOR(SchPortMode_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_sched->sched.queue_sched.queue.gport, cmd, &sch_port_mode);
        value = GetSchPortMode(V,spBitmap_f,&sch_port_mode);
        CTC_BIT_UNSET(value,p_sched->sched.queue_sched.queue.queue_id);
        SetSchPortMode(V,spBitmap_f,&sch_port_mode,value);
        cmd = DRV_IOW(SchPortMode_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, p_sched->sched.queue_sched.queue.gport, cmd, &sch_port_mode);

        cmd = DRV_IOR(QueueWeight_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, queue_id, cmd, &queue_weight);
        SetQueueWeight(V,weight_f,&queue_weight,p_sched->sched.queue_sched.exceed_weight);
        cmd = DRV_IOW(QueueWeight_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip,queue_id, cmd, &queue_weight);
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_get_sched(uint8 lchip, ctc_qos_sched_t* p_sched)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd   = 0;
    uint8  value  = 0;
    uint32 queue_id  = 0;
    SchPortMode_m sch_port_mode;
    QueueWeight_m  queue_weight;
    CTC_PTR_VALID_CHECK(p_sched);
    CTC_MAX_VALUE_CHECK(p_sched->sched.queue_sched.queue.queue_id,CTC_ASW_QOS_MAX_QUE_ID);
    CTC_MAX_GPORT_CHECK(p_sched->sched.queue_sched.queue.gport);

    if ((p_sched->sched.queue_sched.cfg_type != CTC_QOS_SCHED_CFG_EXCEED_CLASS) && (p_sched->sched.queue_sched.cfg_type
    != CTC_QOS_SCHED_CFG_EXCEED_WEIGHT))
    {
        return CTC_E_INVALID_PARAM;
    }

    CTC_API_LOCK(lchip);
    queue_id = (p_sched->sched.queue_sched.queue.gport<<3) + p_sched->sched.queue_sched.queue.queue_id;
    cmd = DRV_IOR(SchPortMode_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, p_sched->sched.queue_sched.queue.gport, cmd, &sch_port_mode);
    value = GetSchPortMode(V,spBitmap_f,&sch_port_mode);
    p_sched->sched.queue_sched.exceed_class = CTC_IS_BIT_SET(value,p_sched->sched.queue_sched.queue.queue_id);
    cmd = DRV_IOR(QueueWeight_t, DRV_ENTRY_FLAG);
    ret = ret?ret:DRV_IOCTL(lchip, queue_id, cmd, &queue_weight);
    p_sched->sched.queue_sched.exceed_weight = GetQueueWeight(V,weight_f,&queue_weight);
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
_ctc_asw_qos_cfg_cpu_reason_dest(uint8 lchip, ctc_qos_queue_cpu_reason_dest_t* p_reason, uint8 is_cfg)
{
    int32 ret = CTC_E_NONE;
    ds_t ds;
    uint32 cmd = 0;
    uint16 index = 0;
    uint16 index1 = 0;
    uint32 tbl_id = 0;
    uint32 field_id[CTC_ASW_QOS_CPU_REASON_DST_FLD_CNT] = {0};
    uint32 value[CTC_ASW_QOS_CPU_REASON_DST_FLD_CNT] = {0};
    uint32 action_index = 0;

    if ((p_reason->cpu_reason < CTC_PKT_CPU_REASON_L2_PDU)
        || (p_reason->cpu_reason >= (CTC_PKT_CPU_REASON_L2_PDU+CTC_ASW_SPMAC_KEY_NUM+CTC_ASW_PMAC_KEY_NUM)))
    {
        return CTC_E_NOT_SUPPORT;
    }

    /*field0: redirect enable
    field1: redirect port bitmap
    field2: drop
    field3: copy_to_cpu 
    field4: valid*/
    action_index = p_reason->cpu_reason-CTC_PKT_CPU_REASON_L2_PDU;
    if (action_index < CTC_ASW_SPMAC_KEY_NUM)
    {
        tbl_id = SmacAct_t;
        field_id[0] = SmacAct_redirectEnable_f;
        field_id[1] = SmacAct_redirectPortBitmap_f;
        field_id[2] = SmacAct_drop_f;
        field_id[3] = SmacAct_copyToCpu_f;
        field_id[4] = SmacAct_valid_f;
    }
    else
    {
        tbl_id = PmacAct_t;
        field_id[0] = PmacAct_redirectEnable_f;
        field_id[1] = PmacAct_redirectPortBitmap_f;
        field_id[2] = PmacAct_drop_f;
        field_id[3] = PmacAct_copyToCpu_f;
        field_id[4] = PmacAct_valid_f;
        action_index -= CTC_ASW_SPMAC_KEY_NUM;
    }

    if (is_cfg)
    {
        value[4] = 1; /*must valid enable*/
        if (CTC_PKT_CPU_REASON_TO_LOCAL_PORT == p_reason->dest_type)
        {
            CTC_MAX_GPORT_CHECK(p_reason->dest_port);
            value[0] = 1;
            CTC_BIT_SET(value[1], p_reason->dest_port);
            value[2] = 0;
            value[3] = 0;
        }
        else if (CTC_PKT_CPU_REASON_TO_DROP == p_reason->dest_type)
        {
            value[0] = 0;
            value[1] = 0;
            value[2] = 1;
            value[3] = 0;
        }
        else if (CTC_PKT_CPU_REASON_TO_LOCAL_CPU_ETH == p_reason->dest_type)
        {
            value[0] = 0;
            value[1] = 0;
            value[2] = 1;
            value[3] = 1;
        }
        else
        {
            return CTC_E_INVALID_PARAM;
        }

        for (index = 0; index<CTC_ASW_MAX_SPMAC_GROUP; index++)
        {
            cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
            ret = DRV_IOCTL(lchip, index+CTC_ASW_MAX_SPMAC_GROUP*action_index, cmd, &ds);
            for (index1=0; index1<CTC_ASW_QOS_CPU_REASON_DST_FLD_CNT; index1++)
            {
                DRV_SET_FIELD_V(lchip,tbl_id,field_id[index1],&ds,value[index1]);
            }
            cmd = DRV_IOW(tbl_id, DRV_ENTRY_FLAG);
            ret = ret?ret:DRV_IOCTL(lchip, index+CTC_ASW_MAX_SPMAC_GROUP*action_index, cmd, &ds);
        }
    }
    else
    {
        cmd = DRV_IOR(tbl_id, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, CTC_ASW_MAX_SPMAC_GROUP*action_index, cmd, &ds);
        for(index=0; index<CTC_ASW_QOS_CPU_REASON_DST_FLD_CNT; index++)
        {
            value[index] = DRV_GET_FIELD_V(lchip,tbl_id,field_id[index],&ds);
        }

        if (0 == value[4])
        {
            p_reason->dest_type = CTC_PKT_CPU_REASON_TO_DROP;
            return CTC_E_NOT_EXIST;
        }
        if (1 == value[0])
        {
            p_reason->dest_type = CTC_PKT_CPU_REASON_TO_LOCAL_PORT;
            for(index=0; index<CTC_ASW_MAX_PHY_PORT; index++)
            {
                if (CTC_IS_BIT_SET(value[1], index))
                {
                    p_reason->dest_port = index;
                    break;
                }
            }
        }
        else if ((1 == value[2]) && (0 == value[3]))
        {
            p_reason->dest_type = CTC_PKT_CPU_REASON_TO_DROP;
        }
        else if ((1 == value[2]) && (1 == value[3]))
        {
            p_reason->dest_type = CTC_PKT_CPU_REASON_TO_LOCAL_CPU_ETH;
        }
        else
        {
            return CTC_E_INVALID_PARAM;
        }
    }
 
    return ret;
}

int32
ctc_asw_qos_set_queue(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg)
{
    int32 ret = CTC_E_NONE;
    uint32 cmd = 0;
    ds_t ds;

    CTC_PTR_VALID_CHECK(p_que_cfg);
    if (CTC_QOS_QUEUE_CFG_PRI_MAP == p_que_cfg->type)
    {
        CTC_MAX_VALUE_CHECK(p_que_cfg->value.pri_map.priority, 15);
        CTC_MAX_VALUE_CHECK(p_que_cfg->value.pri_map.queue_select, 7);
    }
    else if (CTC_QOS_QUEUE_CFG_QUEUE_REASON_MAP == p_que_cfg->type)
    {
        CTC_MAX_VALUE_CHECK(p_que_cfg->value.reason_map.queue_id, CTC_ASW_QOS_MAX_CPU_QUE_ID);
        CTC_MAX_VALUE_CHECK(p_que_cfg->value.reason_map.cpu_reason, CTC_PKT_CPU_REASON_MAX_COUNT-1);
    }

    sal_memset(ds, 0, sizeof(ds));

    CTC_API_LOCK(lchip);
    switch (p_que_cfg->type)
    {
    case CTC_QOS_QUEUE_CFG_PRI_MAP:
        cmd = DRV_IOR(Lp2qpMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_que_cfg->value.pri_map.priority, cmd, &ds);
        SetLp2qpMapTable(V, egportQp_f,&ds,p_que_cfg->value.pri_map.queue_select);
        cmd = DRV_IOW(Lp2qpMapTable_t, DRV_ENTRY_FLAG);
        ret = ret ? ret : DRV_IOCTL(lchip, p_que_cfg->value.pri_map.priority, cmd, &ds);
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MAP:
        ret = _ctc_asw_qos_set_cpu_reason_queue(lchip, p_que_cfg->value.reason_map.cpu_reason, p_que_cfg->value.reason_map.queue_id);
        break;
    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST:
        ret = _ctc_asw_qos_cfg_cpu_reason_dest(lchip, &p_que_cfg->value.reason_dest, 1);
        break;
    default:
        ret = CTC_E_INVALID_PARAM;
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_get_queue(uint8 lchip, ctc_qos_queue_cfg_t* p_que_cfg)
{
    uint32 cmd = 0;
    int32 ret = CTC_E_NONE;
    ds_t ds;
    CTC_PTR_VALID_CHECK(p_que_cfg);

    if (CTC_QOS_QUEUE_CFG_PRI_MAP == p_que_cfg->type)
    {
        CTC_MAX_VALUE_CHECK(p_que_cfg->value.pri_map.priority, 15);
    }
    else if (CTC_QOS_QUEUE_CFG_QUEUE_REASON_MAP == p_que_cfg->type)
    {
        CTC_MAX_VALUE_CHECK(p_que_cfg->value.reason_map.cpu_reason, CTC_PKT_CPU_REASON_MAX_COUNT-1);
    }
 
    CTC_API_LOCK(lchip);
    switch (p_que_cfg->type)
    {
    case CTC_QOS_QUEUE_CFG_PRI_MAP:
        cmd = DRV_IOR(Lp2qpMapTable_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, p_que_cfg->value.pri_map.priority, cmd, &ds);
        p_que_cfg->value.pri_map.queue_select = GetLp2qpMapTable(V, egportQp_f,&ds);
        break;

    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_MAP:
        ret = _ctc_asw_qos_get_cpu_reason_queue(lchip, p_que_cfg->value.reason_map.cpu_reason, &p_que_cfg->value.reason_map.queue_id);
        break;
    case CTC_QOS_QUEUE_CFG_QUEUE_REASON_DEST:
        ret = _ctc_asw_qos_cfg_cpu_reason_dest(lchip, &p_que_cfg->value.reason_dest, 0);
        break;
    default:
        ret = CTC_E_INVALID_PARAM;
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}


int32
ctc_asw_qos_query_pool_stats(uint8 lchip, ctc_qos_resrc_pool_stats_t* p_stats)
{
    uint32 cmd = 0;
    int32 ret = CTC_E_NONE;
    ds_t ds;

    CTC_PTR_VALID_CHECK(p_stats);
    if (p_stats->type != CTC_QOS_RESRC_STATS_QUEUE_COUNT)
    {
        CTC_MAX_GPORT_CHECK(p_stats->gport);
    }
    else
    {
        CTC_MAX_GPORT_CHECK(p_stats->queue.gport);
    }

    sal_memset(ds, 0, sizeof(ds));

    CTC_API_LOCK(lchip);
    switch (p_stats->type)
    {
    case CTC_QOS_RESRC_STATS_IGS_PORT_COUNT:
        cmd = DRV_IOR(IngMmuPortCnt_t, DRV_ENTRY_FLAG);
        ret = (DRV_IOCTL(lchip, p_stats->gport, cmd, &ds));
        p_stats->count = GetIngMmuPortCnt(V, cellCnt_f, &ds);
        break;

    case CTC_QOS_RESRC_STATS_IGS_TOTAL_COUNT:
        cmd = DRV_IOR(IngMmuGlbCnt_t, DRV_ENTRY_FLAG);
        ret = (DRV_IOCTL(lchip, 0, cmd, &ds));
        p_stats->count = GetIngMmuGlbCnt(V, cellCnt_f, &ds);
        break;

    case CTC_QOS_RESRC_STATS_EGS_PORT_COUNT:
        SetEgMonitorCtrl(V,monQMode_f, &ds, 1);
        SetEgMonitorCtrl(V,monMode_f, &ds, 0);
        SetEgMonitorCtrl(V,monPid_f, &ds, p_stats->gport);
        cmd = DRV_IOW(EgMonitorCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &ds);
        SetEgMonitorCtrl(V,monMode_f, &ds, 1);
        cmd = DRV_IOW(EgMonitorCtrl_t, DRV_ENTRY_FLAG);
        ret = ret?ret:DRV_IOCTL(lchip, 0, cmd, &ds);

        cmd = DRV_IOR(EgMonPortCnt_t, DRV_ENTRY_FLAG);
        ret = ret?ret:DRV_IOCTL(lchip, 0, cmd, &ds);
        p_stats->count = GetEgMonPortCnt(V, totalCnt_f, &ds);
        break;

    case CTC_QOS_RESRC_STATS_EGS_TOTAL_COUNT:
        cmd = DRV_IOR(EgMmuGlbState_t, DRV_ENTRY_FLAG);
        ret = (DRV_IOCTL(lchip, 0, cmd, &ds));
        p_stats->count = GetEgMmuGlbState(V, totalCnt_f, &ds);
        break;
    case CTC_QOS_RESRC_STATS_QUEUE_COUNT:
        if (CTC_QUEUE_TYPE_NETWORK_EGRESS != p_stats->queue.queue_type
            || (p_stats->queue.queue_id > ((p_stats->queue.gport == _ctc_asw_chip_get_cpu_port(lchip)) ?
            CTC_ASW_QOS_MAX_CPU_QUE_ID:CTC_ASW_QOS_MAX_QUE_ID)))
        {
            CTC_API_UNLOCK(lchip);
            return CTC_E_INVALID_PARAM;
        }

        SetEgMonitorCtrl(V,monQMode_f, &ds, 0);
        SetEgMonitorCtrl(V,monMode_f, &ds, 0);
        SetEgMonitorCtrl(V,monPid_f, &ds, p_stats->queue.gport);
        SetEgMonitorCtrl(V,monQid_f, &ds, p_stats->queue.queue_id);
        cmd = DRV_IOW(EgMonitorCtrl_t, DRV_ENTRY_FLAG);
        ret = DRV_IOCTL(lchip, 0, cmd, &ds);
        SetEgMonitorCtrl(V,monMode_f, &ds, 1);
        cmd = DRV_IOW(EgMonitorCtrl_t, DRV_ENTRY_FLAG);
        ret = ret?ret:DRV_IOCTL(lchip, 0, cmd, &ds);

        cmd = DRV_IOR(EgMonQueueCnt_t, DRV_ENTRY_FLAG);
        ret = ret?ret:DRV_IOCTL(lchip, 0, cmd, &ds);
        p_stats->count = GetEgMonPortCnt(V, totalCnt_f, &ds);
        break;
    default:
        ret = CTC_E_INVALID_PARAM;
    }
    CTC_API_UNLOCK(lchip);
    return ret;
}

int32
ctc_asw_qos_query_policer_stats(uint8 lchip, ctc_qos_policer_stats_t* p_policer_stats)
{
    uint32 cmd = 0;
    ds_t ds;
    int32 ret = CTC_E_NONE;
    uint8 is_aware_color = 0;
    uint32 policer_id = 0;
    uint64 tmp = 0;
    uint32 count[2] = {0};

    CTC_PTR_VALID_CHECK(p_policer_stats);
    CTC_ERROR_RETURN(_ctc_asw_qos_check_and_get_policer_id(lchip, p_policer_stats->type, p_policer_stats->id.policer_id, p_policer_stats->id.gport, &policer_id));
    CTC_API_LOCK(lchip);

    cmd = DRV_IOR(IngressCounterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret?ret:DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(policer_id),cmd,&ds);
    is_aware_color = (CTC_ASW_QOS_POLICER_STATS_COLOR_AWARE ==  GetIngressCounterCtrl(V, ctrl_f, &ds))?1:0;

    cmd = DRV_IOR(IngressCounterTable_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip, CTC_ASW_QOS_POLICER_STATS_ID(policer_id),cmd,&ds);
    if (0 == is_aware_color)
    {
        GetIngressCounterTable(A, byteCnt_f, &ds, &count);
        tmp |= count[1];
        tmp <<= 32;
        tmp |= count[0];
        p_policer_stats->stats.confirm_bytes = tmp;
        p_policer_stats->stats.confirm_pkts = GetIngressCounterTable(V, frameCnt_f, &ds);
    }
    else
    {
        p_policer_stats->stats.confirm_pkts = GetIngressCounterTableView2(V, greenFrameCnt_f, &ds);
        p_policer_stats->stats.confirm_bytes = 0;
        p_policer_stats->stats.exceed_pkts = GetIngressCounterTableView2(V, yellowFrameCnt_f, &ds);
        p_policer_stats->stats.exceed_bytes = 0;
        p_policer_stats->stats.violate_pkts = GetIngressCounterTableView2(V, redFrameCnt_f, &ds);
        p_policer_stats->stats.violate_bytes = 0;
    }
    CTC_API_UNLOCK(lchip);

    return ret;
}

int32
ctc_asw_qos_clear_policer_stats(uint8 lchip, ctc_qos_policer_stats_t* p_policer_stats)
{
    uint32 cmd = 0;
    ds_t ds;
    int32 ret = CTC_E_NONE;
    uint32 policer_id = 0;

    CTC_PTR_VALID_CHECK(p_policer_stats);
    CTC_ERROR_RETURN(_ctc_asw_qos_check_and_get_policer_id(lchip, p_policer_stats->type, p_policer_stats->id.policer_id, p_policer_stats->id.gport, &policer_id));

    CTC_API_LOCK(lchip);
    SetCounterCtrl(V,cntRcEn_f, &ds, 1);
    cmd = DRV_IOW(CounterCtrl_t, DRV_ENTRY_FLAG);
    ret = DRV_IOCTL(lchip,0,cmd,&ds);

    cmd = DRV_IOR(IngressCounterTable_t, DRV_ENTRY_FLAG);
    ret = ret?ret:DRV_IOCTL(lchip,CTC_ASW_QOS_POLICER_STATS_ID(policer_id), cmd,&ds);

    SetCounterCtrl(V,cntRcEn_f, &ds, 0);
    cmd = DRV_IOW(CounterCtrl_t, DRV_ENTRY_FLAG);
    ret = ret?ret:DRV_IOCTL(lchip,0,cmd,&ds);
    CTC_API_UNLOCK(lchip);

    return CTC_E_NONE;
}
